<?php
/*
 * Copyright (c) 2023. ogg. Inc. All Rights Reserved.
 * ogg sit down and start building bugs in sunny weather.
 * Author: Tc <1224663799@qq.com>.
 * LastChangeTime: 2023-02-07 04:16:23
 * ChangeTime: 2023-04-26 10:21:29
 */

declare(strict_types=1);

namespace Hesb\LaravelPlus\Swagger;

use Hesb\LaravelPlus\Annotation\Api;
use Hesb\LaravelPlus\Exception\ApiDocsException;
use Hesb\LaravelPlus\Listener\BootAppRouteListener;
use Illuminate\Support\Facades\Response;
use Symfony\Component\HttpFoundation\File\File;

#[Api(hidden: true)]
class SwaggerController
{
    private string $swaggerUiPath = BASE_PATH . '/vendor/swagger-api/swagger-ui/dist';

    private string $outputDir;

    private array $uiFileList;

    private array $swaggerFileList;

    private SwaggerConfig         $swaggerConfig;

    public function __construct()
    {
        $this->swaggerConfig = make(SwaggerConfig::class);
        $this->outputDir = $this->swaggerConfig->getOutputDir();
        $this->uiFileList = scandir($this->swaggerUiPath);
        $this->swaggerFileList = scandir($this->outputDir);
    }

    public function index()
    {
        $filePath = BASE_PATH . '/vendor/hesb/laravel-plus/src/web/index.html';
        $contents = file_get_contents($filePath);
        $contents = str_replace(['{{$path}}', '{{$url}}'], ['.' . $this->swaggerConfig->getPrefixUrl(), '.' . $this->getSwaggerFileUrl()], $contents);
        return Response::make($contents);
    }

    public function getFile(string $file)
    {
        if (!in_array($file, $this->uiFileList)) {
            throw new ApiDocsException('File does not exist');
        }
        $file = $this->swaggerUiPath . '/' . $file;
        return $this->fileResponse($file);
    }

    public function getJsonFile(string $httpName = "http")
    {
        $file = $httpName . '.json';
        if (!in_array($file, $this->swaggerFileList)) {
            throw new ApiDocsException('File does not exist');
        }
        $filePath = $this->outputDir . '/' . $file;
        return $this->fileResponse($filePath);
    }

    public function getYamlFile(string $httpName = "http")
    {
        $file = $httpName . '.yaml';
        if (!in_array($file, $this->swaggerFileList)) {
            throw new ApiDocsException('File does not exist');
        }
        $filePath = $this->outputDir . '/' . $file;
        return $this->fileResponse($filePath);
    }

    protected function fileResponse(string $filePath)
    {
        $header = [];
        switch (pathinfo($filePath)['extension'] ?? '') {
            case 'js':
            case 'map':
                $header = [
                    'content-type' => 'application/javascript',
                    'cache-control'=> 'max-age=43200'
                ];
                break;
            case 'css':
                $header = [
                    'content-type' => 'text/css',
                    'cache-control'=> 'max-age=43200'
                ];
                break;
        }
        $response = response()->file($filePath,$header);

        return $response;
    }

    private function getSwaggerFileUrl(): string
    {
        return $this->swaggerConfig->getPrefixUrl() . '/http.' . $this->swaggerConfig->getFormat();
    }
}
